package models

import (
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"log"
)

type UserRoom struct {
	UserIdentity     string `bson:"user_identity"`
	RoomIdentity     string `bson:"room_identity"`
	Message_Identity string `bson:"message_identity"`
	RoomType         int    `bson:"room_type"`
	CreatedAt        int64  `bson:"created_at"`
	UpdateAt         int64  `bson:"updated_at"`
}

// 返回数据库相关表名
func (UserRoom) CollectionName() string {
	return "user_room"
}

func GetUserRoomByUIDRID(userIdentity, roomIdentity string) (*UserRoom, error) {
	ur := &UserRoom{}
	filter := bson.D{{"room_identity", roomIdentity}, {"user_identity", userIdentity}}
	err := Mongo.Collection(UserRoom{}.CollectionName()).FindOne(context.Background(), filter).Decode(ur)
	if err != nil {
		return nil, err
	}
	return ur, err
}

// 获取群聊中的用户
func GetUserRoomByRID(roomIdentity string) ([]*UserRoom, error) {
	filter := bson.D{{"room_identity", roomIdentity}}
	cursor, err := Mongo.Collection(UserRoom{}.CollectionName()).Find(context.Background(), filter)
	defer func(cursor *mongo.Cursor, ctx context.Context) {
		err := cursor.Close(ctx)
		if err != nil {

		}
	}(cursor, context.Background())
	if err != nil {
		return nil, err
	}
	urs := make([]*UserRoom, 0)
	for cursor.Next(context.Background()) {
		ur := new(UserRoom)
		err := cursor.Decode(ur)
		if err != nil {
			return nil, err
		}
		urs = append(urs, ur)
	}
	return urs, nil
}

// JudegeUserIsFriend 判断两个用户是否为好友
// 参数:
// - userIdentity1: 用户1的唯一标识
// - userIdentity2: 用户2的唯一标识
// 返回值:
// - bool: 是否为好友，true 表示是好友，false 表示不是好友
// - error: 执行过程中可能出现的错误
func JudegeUserIsFriend(userIdentity1, userIdentity2 string) bool {
	// 保存 userIdentity1 的单聊房间标识
	roomIdentities := make([]string, 0)

	// 构造查询条件，获取 userIdentity1 的单聊房间列表
	filter := bson.D{
		{"user_identity", userIdentity1}, // 用户标识
		{"room_type", 1},                 // 房间类型为单聊
	}

	// 查询房间数据
	cursor, err := Mongo.Collection(UserRoom{}.CollectionName()).Find(context.Background(), filter)
	// 确保游标在函数退出时关闭，避免资源泄露
	defer func(cursor *mongo.Cursor, ctx context.Context) {
		err := cursor.Close(ctx)
		if err != nil {
			// 可在此记录日志或处理关闭错误
		}
	}(cursor, context.Background())

	// 查询过程中发生错误，返回错误
	if err != nil {
		return false
	}

	// 遍历查询结果，将房间标识保存到 roomIdentities 列表中
	for cursor.Next(context.Background()) {
		ur := new(UserRoom)      // 创建 UserRoom 实例
		err := cursor.Decode(ur) // 解码游标中的数据
		if err != nil {
			return false // 解码失败，返回错误
		}
		roomIdentities = append(roomIdentities, ur.RoomIdentity) // 添加房间标识到列表中
	}

	// 构造新的查询条件，检查 userIdentity2 是否存在于这些单聊房间中
	filter = bson.D{
		{"user_identity", userIdentity2},                 // 用户2的唯一标识
		{"room_type", 1},                                 // 房间类型为单聊
		{"room_identity", bson.M{"$in": roomIdentities}}, // 房间标识是否在 roomIdentities 列表中
	}

	// 查询符合条件的文档数量
	count, err := Mongo.Collection(UserRoom{}.CollectionName()).CountDocuments(context.Background(), filter)
	if err != nil {
		return false // 查询失败，返回错误
	}

	// 如果 count 大于 0，说明用户2存在于用户1的单聊房间中，两人是好友
	if count > 0 {
		return true
	}

	// 否则，两人不是好友
	return false
}

func InsertOneUserRoom(ur *UserRoom) error {
	_, err := Mongo.Collection(UserRoom{}.CollectionName()).InsertOne(context.Background(), ur)
	return err
}
func InsertManyUserRoom(urs []*UserRoom) error {
	docs := make([]interface{}, len(urs))
	for i, v := range urs {
		docs[i] = v
	}
	_, err := Mongo.Collection(UserRoom{}.CollectionName()).InsertMany(context.Background(), docs)
	return err
}

func GetUserRoomIdentity(userIdentity1, userIdentity2 string) (string, error) {
	filter := bson.D{
		{"user_identity", userIdentity1},
		{"room_type", 1},
	}
	cursor, err := Mongo.Collection(UserRoom{}.CollectionName()).Find(context.Background(), filter)
	roomIdentities := make([]string, 0)
	if err != nil {
		log.Println(err.Error())
		return "", err
	}
	for cursor.Next(context.Background()) {
		ur := new(UserRoom)
		err := cursor.Decode(ur)
		if err != nil {
			log.Println(err.Error())
			return "", err
		}
		roomIdentities = append(roomIdentities, ur.RoomIdentity)
	}
	ur := new(UserRoom)
	filter = bson.D{
		{"user_identity", userIdentity2},
		{"room_type", 1},
		{"room_identity", bson.M{"$in": roomIdentities}},
	}
	err = Mongo.Collection(UserRoom{}.CollectionName()).FindOne(context.Background(), filter).Decode(ur)
	if err != nil {
		log.Println(err.Error())
		return "", err
	}
	return ur.RoomIdentity, nil
}

func DeleteUserRoom(roomIdentity string) error {
	filter := bson.D{
		{"room_identity", roomIdentity},
	}
	_, err := Mongo.Collection(UserRoom{}.CollectionName()).DeleteOne(context.Background(), filter)
	if err != nil {
		log.Println(err.Error())
		return err
	}
	return nil
}
